extends Sprite

## 角色固有属性
onready var sprite = $Sprite
onready var line = $RoutLine
onready var testLine = $TestLine
var walkType = 0
var steps = 6
var mapSpend = {}
var canWalk:HashMap
var curPoint:Point = Point.new()
var maxX = 0
var maxY = 0
var finishColor = Color(0.29, 0.29, 0.29)
var initColor = Color(1, 1, 1)

## 角色临时属性
var temp_curPoint:Point
var temp_route:ArraySet
var temp_autoRoute:ArraySet
var temp_canWalk:HashMap
var temp_steps:int

enum {
	ACT,
	HANDLE
}
var state = ACT
var finish = false
signal canWalkChange

func initPlayer(config:Dictionary, mapType):
	var configPosition:Vector2 = config.get("position")
	position = configPosition*32
	curPoint.init(configPosition.x, configPosition.y)
	mapSpend = MapFunction.initMapSpend(walkType, mapType)
	temp_route = ArraySet.new()
	temp_route.add(curPoint)
	temp_autoRoute = ArraySet.new()
	temp_steps = steps
	temp_curPoint = curPoint
	var mapTexture = get_parent().get_node("MapTexture")
	maxX= mapTexture.maxY
	maxY= mapTexture.maxY
	
	var reachPoints = ArrayList.new()
	reachPoints.add(curPoint)
	canWalk = CanWalk.getRoutPlan(excludeRouteSpendMap(), temp_route, reachPoints, curPoint, steps, null, maxX, maxY)
	temp_canWalk = canWalk
	


func _on_Button_pressed():
	print("pressed")
	if !finish:
		state = ACT
	var reachPoints = ArrayList.new()
	reachPoints.add(curPoint)
	canWalk = CanWalk.getRoutPlan(excludeRouteSpendMap(), temp_route, reachPoints, curPoint, steps, null, maxX, maxY)
	temp_canWalk = canWalk
	showCanWalkTexture(canWalk)

func _on_Button_button_down():
	state = HANDLE
	
func _on_Button_button_up():
	if !finish:
		var tail = getTailPoint()
		if curPoint.equals(tail):
			print("didnt move")
		else:
			ExecuteMove.execute(self)
			reset()

func reset():
	finish = true
	state = ACT
	line.clear_points()
	testLine.clear_points()
	curPoint = getTailPoint()
	temp_curPoint = getTailPoint()
	temp_route.clear()
	temp_autoRoute.clear()
	temp_steps = steps
#	position = curPoint.toVector()*32
	clearCanWalkTexture()
	sprite.self_modulate = finishColor
	
	yield(ExecuteMove, "finish")
	get_parent().stepOver()

func getTailPoint():
	if !temp_autoRoute.isEmpty():
		return temp_autoRoute.get(temp_autoRoute.size() - 1)
	if !temp_route.isEmpty():
		return temp_route.get(temp_route.size() - 1)

func _process(delta):
	if !finish && state == HANDLE: 
		var point:Point = Util.getMousePosition()
		if !point.equals(temp_curPoint):
			## 处理回头路
#			print("route.size = ", temp_route.size(), ",point=",point.toString())
			if temp_route.contains(point) || temp_autoRoute.contains(point):
				dealGoBack(point)
				return
				
			## 如果不在可移动范围内不做和处理
			if !checkTempCanWalkPoint(point):
				return
			
			else:
				## 如果是正常移动
				var tail:Point = temp_route.get(temp_route.size()-1)
				if point.neighbor(tail):
					temp_curPoint = point
					temp_steps -= mapSpend[Vector2(point.toVector())]
					temp_route.add(point)
					temp_autoRoute.clear()
					move()
				else:
					var tailP = temp_route.get(temp_route.size()-1)
					var reachPoints = ArrayList.new()
					reachPoints.add(tailP)
					temp_canWalk = CanWalk.getRoutPlan(excludeRouteSpendMap(), temp_route, reachPoints, tailP, canWalk.get(tailP).steps, null, maxX, maxY)
					temp_curPoint = point
					var stepRout = temp_canWalk.get(temp_curPoint)
					temp_autoRoute = stepRout.rout
					temp_steps = stepRout.steps
					move()
					

## 处理回头路
func dealGoBack(point):
#	printerr("走到回头路：", point.toString())
	if temp_route.contains(point):
		var removeIndex = temp_route.indexOf(point)
		temp_curPoint = point
		temp_autoRoute.clear()
		## 回滚
		var tt = ArrayList.new()
		tt.copy(temp_route)
		temp_route.clear()
		temp_steps = steps
		for i in range(removeIndex):
			var rout = tt.get(i)
			temp_steps -= mapSpend[rout.toVector()]
	#		print("temp——rout.add:",rout.toString())
			temp_route.add(rout)
		temp_route.add(point)
		move()
	else:
		## 若temp_auto回滚完了
#		print("回滚到点：", point.toString())
		var tail:Point = temp_route.get(temp_route.size()-1)
		if point.neighbor(tail):
			temp_curPoint = point
			temp_autoRoute.clear()
			temp_route.add(point)
			temp_steps = steps
			for i in range(1, temp_route.size()):
				var p = temp_route.get(i)
				temp_steps -= mapSpend[p.toVector()]
			move()
		else:
			var removeIndex = temp_autoRoute.indexOf(point)
			while temp_autoRoute.size()>removeIndex+1:
				var p = temp_autoRoute.get(temp_autoRoute.size()-1)
				temp_steps += mapSpend[p.toVector()]
				temp_autoRoute.remove(temp_autoRoute.size()-1)
			temp_curPoint = point
			move()

func move():
	var reachPoints = ArrayList.new()
	reachPoints.add(temp_curPoint)
	temp_canWalk = CanWalk.getRoutPlan(excludeRouteSpendMap(), temp_route, reachPoints, temp_curPoint, temp_steps, null, maxX, maxY)
	showCanWalkTexture(temp_canWalk)
	drawLine()

func drawLine():
	temp_steps = steps
	line.clear_points()
	testLine.clear_points()
	if !temp_route.isEmpty():
		for i in range(temp_route.arr.size()):
			var p = temp_route.arr[i]
			testLine.add_point((p.toVector()-curPoint.toVector())*64 + Vector2(32,32))
			if i != 0:
				temp_steps -= mapSpend[p.toVector()]
	if !temp_autoRoute.isEmpty():
		for i in range(temp_autoRoute.arr.size()):
			var p = temp_autoRoute.arr[i]
			line.add_point((p.toVector()-curPoint.toVector())*64 + Vector2(32,32))
			if i != 0:
				temp_steps -= mapSpend[p.toVector()]

func excludeRouteSpendMap()->Dictionary:
	var newMap = mapSpend
	for p in temp_route.arr:
		newMap[Vector2(p.x, p.y)] = mapSpend[Vector2(p.x, p.y)]
	return newMap
	
func showCanWalkTexture(canWalk:HashMap):
	clearCanWalkTexture()
	var mapTexture = get_parent().get_node("MapTexture")
	var list = canWalk.keys()
	mapTexture.canWalkChange(list.arr)

func clearCanWalkTexture():
	var mapTexture = get_parent().get_node("MapTexture")
	mapTexture.clearWalk()
	

func checkTempCanWalkPoint(point)->bool:
	var points:ArrayList = temp_canWalk.keys()
#	for p in points.arr:
#		print(p.toString())
#	printerr(point.toString())
	return points.contains(point)
